import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateFilter;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;

public class bloodvesselNormalizer {

	static final double TRIANGULATION_TOLERANCE = 0.0;
	static GeometryFactory fact = new GeometryFactory();
	static WKTReader wktRdr = new WKTReader(fact);
	static final String quote = "\"";
	static final List<Geometry> vessels = new ArrayList<Geometry>();
	static final HashMap<String, List<Point>> tileMap = new HashMap<String, List<Point>>();
	static final HashMap<String, Envelope> tileBox = new HashMap<String, Envelope>();
	static final List<Point> cloud = new ArrayList<Point>();

	public static void normalizeGeometry(Geometry g) {
		class MyCoordinateFilter implements CoordinateFilter {
			private double minX;
			private double minY;

			public MyCoordinateFilter(double x, double y) {
				this.minX = x;
				this.minY = y;
			}

			@Override
			public void filter(Coordinate coord) {
				coord.x = coord.x - this.minX;
				coord.y = coord.y - this.minY;
			}
		}
		Envelope mbb = g.getEnvelopeInternal();
		g.apply(new MyCoordinateFilter(mbb.getMinX(), mbb.getMinY()));
		g.geometryChanged();
	}

	public static void loadBloodVessels(File f) {
		try {
			BufferedReader br = new BufferedReader(new FileReader(f));
			String line;
			while ((line = br.readLine()) != null) {
				// String Image_ID = line.substring(0,line.indexOf(','));
				String shape = line.substring(line.indexOf(quote) + 1,
						line.lastIndexOf(quote));
				Geometry g = wktRdr.read("POLYGON((" + shape + "))");
				normalizeGeometry(g);
				vessels.add(g);
			}
		} catch (FileNotFoundException e) {
			System.err.println("There is NO such a file: " + f.toString());
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

	public static void loadCellsByTile(File f) {

		File[] tiles = f.listFiles();
		BufferedReader br;
		String line;

		for (File tile : tiles) {
			try {
				br = new BufferedReader(new FileReader(tile));

				while ((line = br.readLine()) != null) {
					String Image_ID = line.substring(0, line.indexOf(','));
					String Tile_ID = line.substring(line.indexOf(',') + 1,
							line.indexOf(quote) - 1);
					String shape = line.substring(line.indexOf(quote) + 1,
							line.lastIndexOf(quote));

					if (!tileMap.containsKey(Tile_ID))
						tileMap.put(Tile_ID, new ArrayList<Point>());

					Point p = wktRdr.read("POLYGON( " + shape + "))")
							.getCentroid();
					tileMap.get(Tile_ID).add(p);
					cloud.add(p);

					if (!tileBox.containsKey(Tile_ID)) {
						tileBox.put(Tile_ID, new Envelope(p.getCoordinate()));
					} else {
						tileBox.get(Tile_ID).expandToInclude(p.getCoordinate());
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static int getRandomNumber(int limit) {
		Random r = new Random();
		return r.nextInt(limit);
	}

	public static String getContainerTile(Point p) {
		// TODO implement the method
		return null;
	}

	public static void dojob() {
		List<Geometry> out_vessels = new ArrayList<Geometry>();
		Geometry vessel;
		Point p;
		String Tile_ID;

		while (vessels.size() > 0) {
			vessel = vessels.remove(getRandomNumber(vessels.size()));
			p = cloud.get(getRandomNumber(cloud.size()));
			Tile_ID = getContainerTile(p);
			while (true) {
				Point base = tileMap.get(Tile_ID).get(
						getRandomNumber(tileMap.get(Tile_ID).size()));
				
			}
		}
	}

	public static void main(String[] args) {

		if (args.length < 2) {
			System.err.println("Usage: bloodvesselNormalizer [image tiles dir] [blood vessel file]");
			System.exit(0);
		}

		File tileDir = new File(args[0]);
		File bvFile = new File(args[1].trim());

		if (!tileDir.isDirectory()) {
			System.err.println("WARNING: " + tileDir.toString()
					+ " is NOT a directory.");
			System.exit(0);
		}

		loadBloodVessels(bvFile);
		loadCellsByTile(tileDir);
		dojob();
	}
}
